package com.stations.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReportMsgUtils {
    private static final Logger log = LoggerFactory.getLogger(ReportMsgUtils.class);

    /**
     * 16进制字符串 转换为对应的 byte数组
     *
     * @param hex hex
     * @return byte[]
     * @author Ljy
     * @date 2021/3/9 17:20
     */
    public static byte[] hex2Bytes(String hex) {
        if (hex == null || hex.length() == 0) {
            return null;
        }
        char[] hexChars = hex.toCharArray();
        byte[] bytes = new byte[hexChars.length / 2]; // 如果 hex 中的字符不是偶数个, 则忽略最后一个

        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);
        }

        return bytes;
    }

    /**
     * 将16进制字符串转换为byte数组
     *
     * @param
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.trim().replaceAll("\\s*", ""); // 去除字符串中的空格

        String hexFormat = "0123456789ABCDEF";

        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (hexFormat.indexOf(hexChars[pos]) << 4 | hexFormat
                    .indexOf(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * 16进制转换MAC地址
     *
     * @param mac_orig mac_orig
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:21
     */
    public static String transMac(String mac_orig) {
        StringBuilder mac = new StringBuilder();
        if (null == mac_orig || mac_orig.length() != 18) {
            return null;
        }
        int sin_length = 3;
        while (mac_orig.length() > 0) {
            String sin_str = mac_orig.substring(0, sin_length);
            int sin_int = Integer.parseInt(sin_str);
            String hex_str = Integer.toHexString(sin_int);
            if (sin_int <= 15) {
                hex_str = "0" + hex_str;
            }
            mac.append(hex_str);
            mac_orig = mac_orig.substring(sin_length);
        }
        if ("".equals(mac.toString())) {
            mac = null;
        }
        return null == mac ? null : mac.toString().toUpperCase();
    }

    /**
     * 16进制转换IP地址
     *
     * @param ip_hex ip_hex
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:21
     */
    public static String hex_to_ip(String ip_hex) {
        StringBuilder ip = new StringBuilder();
        if (null == ip_hex || ip_hex.length() != 8) {
            log.info("待转换格式错误");
            return "";
        }
        int sin_length = 2;
        while (ip_hex.length() > 0) {
            String sin_str = ip_hex.substring(0, sin_length);
            int sin_int = Integer.parseInt(sin_str, 16);
            String hex_str = Integer.toString(sin_int);
            if (ip_hex.length() > 2) {
                ip.append(hex_str).append(".");
            } else {
                ip.append(hex_str);
            }
            ip_hex = ip_hex.substring(sin_length);
        }
        return ip.toString();
    }

    /**
     * 16进制转换FM信号强度, 及信号质量
     *
     * @param fm_hex fm_hex
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:22
     */
    public static String to_fm_hex(String fm_hex) {
        // 信号强度
        String si = fm_hex.substring(0, 2);
        // 信号质量
        String sq = fm_hex.substring(2);
        int _si = 0;
        int _sq = 0;
        if (!si.equals("00")) {
            _si = Integer.parseInt(si, 16);
        } else if (!sq.equals("00")) {
            _sq = Integer.parseInt(sq, 16);
        }
        return _si + "," + _sq;
    }

    /**
     * 16进制转有线频率: 主频+符号率+QAM
     *
     * @param KhzKbpsQam KhzKbpsQam
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:22
     */
    public static String to_KhzKbpsQam(String KhzKbpsQam) {
        String mf = KhzKbpsQam.substring(0, 8);// 主频
        String sr = KhzKbpsQam.substring(8, 16); // 符号率
        String qam = KhzKbpsQam.substring(16);// QAM
        int _mf = 0;
        int _sr = 0;
        int _qam = 0;
        if (!mf.equals("00000000")) {
            _mf = Integer.parseInt(mf, 16);
        }
        if (!sr.equals("00000000")) {
            _sr = Integer.parseInt(sr, 16);
        }
        if (!qam.equals("00")) {
            _qam = Integer.parseInt(qam, 16);
        }
        return _mf + "," + _sr + "," + _qam;
    }

    /**
     * 主频率, 符号率, QAM;10进制转换16进制
     *
     * @param freq   主频率
     * @param symbol 符号率
     * @param qam    QAM
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:23
     */
    public static String freqsymbolQAM_tohex(String freq, String symbol, String qam) {
        int _freqs = 0;
        int _symbols = 0;
        int _qams = 0;
        if (!"000000".equals(freq)) {
            _freqs = Integer.parseInt(freq);
        }
        if (!"0000".equals(symbol)) {
            _symbols = Integer.parseInt(symbol);
        }
        if (!"00".equals(qam)) {
            _qams = Integer.parseInt(qam);
        }
        String _freq = String.format("%08x", _freqs);
        String _symbol = String.format("%08x", _symbols);
        String _qam = String.format("%02x", _qams);
        return _freq + _symbol + _qam;
    }

    /**
     * FM扫描频点列表解析 频点数1B+{频点序号1b,优先级1b,频率3b....}
     *
     * @param frelist frelist
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:23
     */
    public static String to_FmScanFrelist(String frelist) {
        int num = 0;
        StringBuilder sum = new StringBuilder();
        String frepointnum;// 频点序号
        String priority;// 优先级
        String frequency;// 频率
        if (!"00".equals(frelist.substring(0, 2))) {
            int frenum = Integer.parseInt(frelist.substring(0, 2), 16);
            num += 2;
            for (int i = 1; i <= frenum; i++) {
                frepointnum = frelist.substring(num, num + 2);
                int frepointnums = Integer.parseInt(frepointnum, 16);
                num += 2;
                priority = frelist.substring(num, num + 2);
                int prioritys = Integer.parseInt(priority, 16);
                num += 2;
                frequency = frelist.substring(num, num + 6);
                int frequencys = Integer.parseInt(frequency);
//				Integer integer = Integer.parseInt(frequency.substring(0,4));   跟实际对接设备确认解析方式是否按照BCD编码解析
//				String decimal =String.format("%02d", Integer.parseInt(frequency.substring(5)));
                num += 6;
                sum.append(frepointnums).append(",").append(prioritys).append(",").append(frequencys).append(";");
//				sum += frepointnums.toString()+","+prioritys.toString()+","+integer.toString()+"."+decimal+";";
            }
        } else {
            sum = new StringBuilder("00");
        }

        return sum.toString();
    }

    /**
     * 16进制转二进制以BCD编码形式输出10进制数值, 资源编码专用
     *
     * @param hexString hexString
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:24
     */
    public static String to_Bcd(String hexString) {
        StringBuilder to_bcd = new StringBuilder();
        if (hexString == null || hexString.length() % 2 != 0)
            return null;
        String[] bString1 = new String[24];
        String tmp;
        // 转换二进制
        for (int i = 0; i < hexString.length(); i++) {
            tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
            bString1[i] = tmp.substring(tmp.length() - 4);
        }
        // 按照BCD编码格式转换10进制
        for (int i = 1; i < bString1.length; i++) {
            String _q;
            int q = Integer.parseInt(bString1[i], 2);
            _q = Integer.toString(q);
            to_bcd.append(_q);
        }
        return to_bcd.toString();
    }

    /**
     * 16进制转换时间格式
     *
     * @param timehex timehex
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:25
     */
    public static String to_timehex(String timehex) {
        SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int timeHex = Integer.parseInt(timehex, 16);
        long lt = new Long(Integer.toString(timeHex));
        Date time = new Date(lt * 1000);
        return sp.format(time);
    }

    // 生成<String>list
    public static ArrayList<String> makelist(byte[] msg, int[] n, int s) {
        ArrayList<String> list = new ArrayList<>();
        for (int j : n) {
            String str = bytetostring(msg, s, j);
            list.add(str);
            s = s + j;
        }
        return list;
    }

    // byte数组转String
    public static String bytetostring(byte[] msg, int s, int n) {
        int max = s + n;
        if (max > msg.length || s > msg.length || n < 0 || s < 0) {
            log.info("该数据信息未找到！开始位置：" + s + "字节,长度：" + n);
            return "";
        } else {
            byte[] gcf = new byte[n];
            System.arraycopy(msg, s, gcf, 0, n);
            return Objects.requireNonNull(bytesToHexString(gcf)).replaceAll(" ", "");
        }
    }

    // 数组int求和
    public static int sumns(int sum, int[] n) {
        for (int j : n) {
            sum += j;
        }
        return sum;
    }

    /**
     * 取应急广播消息覆盖资源编码生成数组, 根据资源编码 recodenum数量 ,recodelen长度 生成
     *
     * @param msg       msg
     * @param sum       字段位置
     * @param recodenum 资源编码数量
     * @param recodelen 资源编码长度
     * @param data      data
     * @return java.lang.String[]
     * @author Ljy
     * @date 2021/3/9 17:26
     */
    public static String[] resource_code(byte[] msg, int sum, int recodenum, int recodelen, String[] data) {
        data = new String[recodenum];
        for (int i = 0; i < recodenum; i++) {
            String str = bytetostring(msg, sum, recodelen);
            data[i] = str;
            sum += recodelen;
        }
        return data;
    }

    /**
     * 查询多个参数数组
     *
     * @param msg   消息体
     * @param s     位置
     * @param n     n
     * @param n2    n2
     * @param datas datas
     * @return java.lang.String[][]
     * @author Ljy
     * @date 2021/3/9 17:29
     */
    public static String[][] output_queryinfo(byte[] msg, int s, int n, int n2, String[][] datas) {
        if (n2 == 2) {
            datas = new String[n][n2];
            for (int i = 0; i < n; i++) {
                datas[i][0] = bytetostring(msg, s, 1);
                s = s + 1;
                datas[i][1] = bytetostring(msg, s, 1);
                s = s + 1;
            }
            return datas;
        } else if (n2 == 3) {
            datas = new String[n][n2];
            for (int i = 0; i < n; i++) {
                datas[i][0] = bytetostring(msg, s, 1);
                s = s + 1;
                datas[i][1] = bytetostring(msg, s, 1);
                int num = Integer.parseInt(Objects.requireNonNull(bytetostring(msg, s, 1)), 16);
                s = s + 1;
                datas[i][2] = bytetostring(msg, s, num);
                s = s + num;
            }
            return datas;
        }
        return null;
    }

    /**
     * 适配器任务上报转电话号码
     *
     * @param tel tel
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:31
     */
    public static String to_telphone(String tel) {
        String result;
        // 16进制字符
        String hexDigital = "0123456789ABCDEF";
        // 将16进制字符串转换成char数组
        char[] hexs = tel.toCharArray();
        // 能被16整除，肯定可以被2整除
        byte[] bytes = new byte[tel.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = hexDigital.indexOf(hexs[2 * i]) * 16 + hexDigital.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        result = new String(bytes, StandardCharsets.UTF_8);
        return result;
    }

    /// 疏附县

    /**
     * 16进制字符串转2进制字符串（高位自动补0）
     *
     * @param Hex Hex
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:32
     */
    public static String to_Binary(String Hex) {
        int j = Integer.parseInt(Hex, 16);
        StringBuilder str = new StringBuilder(Integer.toBinaryString(j));
        for (int i = str.length(); i < Hex.length() * 4; i++) {
            str.insert(0, "0");
        }
        return str.toString();
    }

    /**
     * 16进制字符串转10进制字符串（带i位小数）
     *
     * @param Hex Hex
     * @param i   i
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:33
     */
    public static String to_Decimal(String Hex, int i) {
        int j = i + 1;
        String str = String.format("%0" + j + "d", Integer.parseInt(Hex, 16));
        str = str.substring(0, str.length() - i) + "." + str.substring(str.length() - i);
        return str;
    }

    /**
     * 浮点型经纬度转的String字符串
     *
     * @param s s
     * @return java.lang.String
     * @author Ljy
     * @date 2021/3/9 17:33
     */
    public static String to_lonlat(String s) {
        String news = s.substring(6, 8) + s.substring(4, 6) + s.substring(2, 4) + s.substring(0, 2);
        Float x = Float.intBitsToFloat(Integer.parseInt(news, 16));
        return String.valueOf(x);
    }

    /**
     * 16进制转换时间
     *
     * @param timehex timehex
     * @return java.util.Date
     * @author Ljy
     * @date 2021/3/9 17:33
     */
    public static Date to_timehexs(String timehex) {
        Long timeHex = Long.parseLong(timehex, 16);
        return new Date(timeHex * 1000);
    }

    public  static String strtoascii(String ebm_type){
        if(ebm_type.length()!=5){
            return "3030303030";
        }
        byte[] ebm_types = ebm_type.getBytes(StandardCharsets.US_ASCII);
        return ReportMsgUtils.bytesToHexString(ebm_types).replace(" ","");
    }

    public static String asciitostr(String value){//ASCII转换为字符串

        String regex = "(.{2})";
        value = value.replaceAll(regex, "$1 ");
        String[]chars=value.split(" ");
        String rs = "";
        for(int i=0;i<chars.length;i++){
            rs = rs + (char)Integer.parseInt(chars[i],16);
        }
        return rs;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
    /* 字符串转换成为16进制字符串（大写）
     * @explain 因为java转义字符串在java中有着特殊的意义，
     *     所以当字符串中包含转义字符串，并将其转换成16进制后，16进制再转成String时，会出问题：
     *  java会将其当做转义字符串所代表的含义解析出来
     * @param str 字符串（去除java转义字符）
     * @return 16进制字符串
     * @throws Exception
     */
    public  static String toHexString(String str)  {
        // 用于接收转换结果
        String hexString = "";
        // 1.校验是否包含特殊字符内容
        // java特殊转义符
        // String[] escapeArray = {"\b","\t","\n","\f","\r","\'","\"","\\"};
        String[] escapeArray = {};
        // 用于校验参数是否包含特殊转义符
        boolean flag = false;
        // 迭代
        for (String esacapeStr : escapeArray) {
            // 一真则真
            if (str.contains(esacapeStr)) {
                flag = true;
                break;// 终止循环
            }
        }
        // 包含特殊字符
        if (flag) return "";

        // 16进制字符
        char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        StringBuilder sb = new StringBuilder();
        // String--&gt;byte[]
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i<bs.length; i++) {
            bit = (bs[i] & 0x0f0)>>4;
            sb.append(hexArray[bit]);
            bit = bs[i] & 0x0f;
            sb.append(hexArray[bit]);
        }
        hexString = sb.toString();
        return hexString;
    }
    /**
     * 正则提前字符串中的IP地址
     * @param ipString
     * @return
     */
    public static List<String> getIps(String ipString){
        String regEx="((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
        List<String> ips = new ArrayList<String>();
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(ipString);
        while (m.find()) {
            String result = m.group();
            ips.add(result);
        }
        return ips;
    }

    public static String sub(StringBuilder data, int n) {
        String x = data.substring(0, n);
        data.delete(0, n);
        return x.toUpperCase();
    }

    /***
     * @Title: Stringfor
     * @Description //等长数组截取并移除
     * @Author GCF
     * @Date 2021/10/20 18:10
     * @Param [data, length, sum]
     * @return java.lang.String[]
     **/
    public static String[] stringFor(StringBuilder data, int length, int sum) {
        String[] s = new String[sum];
        for (int i = 0; i < sum; i++) {
            s[i] = data.substring(0, length);
            data.delete(0, length);
        }
        return s;
    }

    /***
     * @Title: crc
     * @Description // CRC验证
     * @Author GCF
     * @Date 2021/8/11 19:07
     * @Param [msg, sum]
     * @return java.lang.String
     **/
    public static boolean crcCheck(byte[] msg, int dataLength) {
        String code = "00";
        boolean flag = false;
        String crc = ReportMsgUtils.bytetostring(msg, dataLength - 4, 4); // crc 获取
        String msgs = ReportMsgUtils.bytetostring(msg, 0, dataLength - 4);
        return crc.equals(CRC32.CRC32_MPEG_2_Str(msgs));
    }

    public static String hexipportToStr(String ip_hex) {
        StringBuilder ip = new StringBuilder();
        if (null == ip_hex || ip_hex.length() != 12) {
            log.info("待转换格式错误");
            return null;
        }
        int ip1 = Integer.parseInt(ip_hex.substring(0,2), 16);
        int ip2 = Integer.parseInt(ip_hex.substring(2,4), 16);
        int ip3 = Integer.parseInt(ip_hex.substring(4,6), 16);
        int ip4 = Integer.parseInt(ip_hex.substring(6,8), 16);
        int port = Integer.parseInt(ip_hex.substring(8,12), 16);
        ip.append(ip1+"."+ip2+"."+ip3+"."+ip4+":"+port);

        return ip.toString();
    }

    public static void main(String args[]){
//        String aaa = "{aaa:1,bbb:2}";
//        String asd = ReportMsgUtils.bytesToHexString(aaa.getBytes());
//        String cccc = ReportMsgUtils.hexStringToString(asd);
//        System.out.println(cccc);
        hexipportToStr("c0a8003c2775");
        System.out.println( String.format("%4x",16+1));

    }
}
